<?php
/**
* 声明并实现文章处理的功能函数
*/

/**
* 如何计算问题的最精准的相似结果？
* 1、对标题进行关键词分析
* 2、对描述进行关键词分析
* 3、将两者关键词，按照8-2比例分配权重
* 4、生成包含关键词和关键词对应权重的数组
* 5、用数组与文库中内容进行相似度计算，得出相似文章
*/

#测试包含改文件是否成功
$justTestNum = 10101010;

/**
* @name   get_savable_vector 获取可用来直接存储的向量字符串
* @param  string title    待处理的标题或问题
* @param  string content  待处理的内容或描述
* @return string seriaStr 返回可直接用于存储于数据库的经过序列化的数组字符串
*/
function get_savable_vector( $title , $content ){

	$titleVct   = get_valid_words( $title );
	$contentVct = get_valid_words( $content );
	$qstVector = get_question_vector( $titleVct , $contentVct );

	return array_serialize( $qstVector );
}


/**
* @func 去除分词结果中无效属性的词汇，包括助词、标点符号
* @param   string needle 待处理的字符串
* @return  array  retArr  
*/
function get_valid_words( $needle = '' ){
	require_once( '../aip/AipNlp.php');
	$aipnlp = new AipNlp( '9947118', 'YdIHRWObHws1q250Ba8G3FHE', 'owzgxMD3g9W7CfRITNCxeFSKcXOdpzWD' );
	$deltypeArr = array( 'w' , 'u' , 'p' , 'xc' , 'c' );
	$retArr     = array();

	if( !mb_strlen($needle) ){
		echo "待处理的字符串为空";
		return fasle;
	}else{
		@$wordArr = $aipnlp->lexer( $needle );	
	}

	foreach ( (array)@$wordArr['items'] as $word ) {
		if( !in_array( @$word['pos'] , $deltypeArr) ){
			$retArr[] = @$word['item'];
		}
	}

	return $retArr;
}

/**
* @name get_question_vector 获取问题的分析向量
* @param  array qstwordArr
* @param  array smrwordArr
* @return array qstVector 返回词汇向量
*/
function get_question_vector( $qstwordArr = array() , $smrwordArr = array() ){
	//1、获取分词及词汇数量数组
	@$qstwdcountArr = get_word_count( $qstwordArr );
	@$smrwdcountArr = get_word_count( $smrwordArr );

	//2、weighting ，数组加权
	@$qstwdweightArr = get_word_weight( $qstwdcountArr , 4 );
	@$smrwdweightArr = get_word_weight( $smrwdcountArr , 1 );

	//3、问题及描述加权数组合并
	$qstVector = mergewhtArr( $qstwdweightArr , $smrwdweightArr );

	return $qstVector;
}

/**
* @name get_word_count 获取包含词，及其对应数量的数组
* @param array qstwordArr
*/
function get_word_count( $qstwordArr = array() ){
	if( empty($qstwordArr) ){
		return false;
	}else{
		return array_count_values( $qstwordArr );
	}
}

/**
* @name   get_word_weight 获取赋予权重之后的数组
* @param  array wdcountArr
* @param  int   weight
* @return array wdweightVector
*/
function get_word_weight( $wdcountArr = array() , $weight = 1 ){
	if( empty($wdcountArr) ){
		return false;
	}else{
		foreach ($wdcountArr as $word => $count) {
			$wdcountArr[$word] = $count * $weight;
		}
	}

	return $wdcountArr;
}

/**
* @name   mergewhtArr 合并问题和描述的加权数组
* @param  array qstwhtArr
* @param  array smrwhtArr
* @return array qstwhtArr 返回统一的问题向量
*/
function mergewhtArr( $qstwhtArr = array() , $smrwhtArr = array() ){

	foreach ((array)$qstwhtArr as $qstwht => $qstvalue) {
		if( isset($smrwhtArr[$qstwht]) ){
			$qstwhtArr[$qstwht] = $qstvalue + $smrwhtArr[$qstwht];
		}else{
			$qstwhtArr[$qstwht] = $qstvalue;
		}
	}

	foreach ((array)$smrwhtArr as $smrwht => $smrvalue) {
		if( !isset($qstwhtArr[$smrwht]) ){
			$qstwhtArr[$smrwht] = $smrvalue;
		}else{
			continue;
		}
	}

	return $qstwhtArr;
}

/**
* @name   array_serialize 将数组序列化
* @param  array needle 待处理的数组
* @return string serialized 处理后的数组字符串
*/
function array_serialize( $needle = array() ){
	if( is_array($needle) && !empty($needle) ){
		$serialized = addslashes( serialize( $needle ) );
		return $serialized;
	}else{
		return false;
	}
}

/**
* @name   array_unserialize 将字符串反序列化成字符串
* @param  string needle  待处理的字符串
* @return array  unserialized
*/
function array_unserialize( $needle = '' ){
	if( is_string( $needle ) ){
		$unserialized = unserialize( stripslashes( $needle ) );
		return $unserialized;
	}else{
		return false;
	}
}

/**
* 存储前对字符串进行优化
* @name    optimdocument
* @param   string document
* @return  string document
*/
function optimdocument( $document = '' ){
	if( is_string($document) && mb_strlen($document) ){
		$document = trim( strip_tags( $document ) );
		return preg_replace( '/\s/', '', $document);
	}
}

////////////////////////////////////////////////////////
/**
* PDO数据库操作类
*/
class wp_pdo{
	private $name = 'wp';
	private $user = 'root';
	private $pswd = '';
	public  $wpPdo;

	public function __construct(){
		#转换编码，否则数据库读取汉字为？
		$_opts_values = array(PDO::ATTR_PERSISTENT=>true,PDO::ATTR_ERRMODE=>2,PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES utf8');
		$this->wpPdo = new PDO("mysql:host=localhost; dbname=$this->name", $this->user , $this->pswd, $_opts_values);
	}

	/**
	* @name   get_article_vector 获取wp_article表中的文章向量
	* @return array allArtiVct
	*/
	public function get_article_vector(){
		try{
			$allArtiVct = $this->wpPdo->query('SELECT id,vector FROM wp_article');	
		}catch(PDOException $e){
			exit("数据库读取出错：" . $e);
		}

		return $allArtiVct->fetchAll();
	}

	/**
	* @name get_article_tstu 获取wp_article表中，记录的title,summary,tags,url
	* @return array tstuArr
	*/
	public function get_article_tstu(){
		$tstuArr = $this->wpPdo->query( 'SELECT title,summary,tags,url FROM wp_article');

		return $tstuArr->fetchAll();
	}

	/**
	* @name   getArtById 根据id数组，抓取相应的文章
	* @param  array id
	* @return array artArr
	*/
	public function getArtById( $id ){
		if( is_numeric( $id ) ){
			@$articles = $this->wpPdo->query( "SELECT title,summary,url FROM wp_article WHERE id=$id",PDO::FETCH_ASSOC );
			return $articles->fetchAll();

		}elseif( is_array( $id ) ){
			foreach ($id as $i) {
				@$tmp = $this->wpPdo->query("SELECT title,summary,url FROM wp_article WHERE id=$i",PDO::FETCH_ASSOC );
				$articles[] = $tmp->fetchAll()[0];
			}

			return $articles;
		}
	}

	/**
	* @name   getInfoById  通过id获取数据库信息
	* @param  string db 操作的数据库
	* @param  int    id 
	* @return array  info
	*/
	public function getInfoById( $db = '' , $id = 0 ){
		$info = array();

		$info = $this->wpPdo->query("SELECT * FROM $db WHERE id=$id" , PDO::FETCH_ASSOC );
		return $info->fetchAll();
	}



	////////////////////关键词操作////////////////////////
	/**
	* @name   getKwdById  通过id获得关键词
	* @param  int     id
	* @return string  word
	*/
	public function getKwdById( $id = 0 ){
		$word = $this->wpPdo->query( "SELECT text FROM wp_keyword WHERE id=$id" , PDO::FETCH_NUM );
		return $this->reduceArrDimens( $word->fetchAll() );
	}

	/**
	* @name   getKwdByLen   通过关键词长度查询固定长度关键词
	* @param  int    length
	* @return string word
	*/
	public function getKwdByLen( $length = 0 ){
		$word = $this->wpPdo->query( "SELECT text FROM wp_keyword WHERE length=$length" , PDO::FETCH_NUM );
		return $this->reduceArrDimens( $word->fetchAll() );
	}

	/**
	* @name   getkwdByLen_short  查询小于某一长度的关键词,并按长度倒叙排列
	* @param  int   length
	* @return array word
	*/
	public function getkwdByLen_short( $length = 0 ){
		$word = $this->wpPdo->query( "SELECT text FROM wp_keyword WHERE length<$length ORDER BY length DESC" , PDO::FETCH_NUM );
		return $this->reduceArrDimens( $word->fetchAll() );
	}

	/**
	* @name   getKwdByLen_long  查询大于某一长度的关键词,并按长度倒叙排列
	* @param  int   length
	* @return array word
	*/
	public function getkwdByLen_long( $length = 0 ){
		$word = $this->wpPdo->query( "SELECT text FROM wp_keyword WHERE length>$length ORDER BY length DESC" , PDO::FETCH_NUM );
		return $this->reduceArrDimens( $word->fetchAll() );
	}

	/**
	* @name   getKwdByLike   通过like查找相似关键词,并按长度倒叙排列
	* @param  string   subWord
	* @return array    word
	*/
	public function getKwdByLike( $subWord = '' ){
		try{
			#注意：like后的变量要加引号
			$word = $this->wpPdo->query( "SELECT text FROM wp_keyword WHERE text LIKE '%$subWord%' ORDER BY length DESC" , PDO::FETCH_NUM );	
			return $this->reduceArrDimens( $word->fetchAll() );
		}catch( PDOException $e ){
			echo "like获取数据异常<br>";
			var_dump( $e );
		}
	}

	/**
	* @name   getArtByLike   通过关键词匹配来获取相似的文章
	* @param  string   kwd
	* @return array    artInfo
	*/
	public function getArtByLike( $kwd = '' ){
		try{
			@$artInfo = $this->wpPdo->query( "SELECT * FROM wp_article WHERE title LIKE '%$kwd%'" , PDO::FETCH_ASSOC );
			return $artInfo->fetchAll();
		}catch( PDOException $e ){
			echo "通过关键词获取相似文章失败，原因：";
			var_dump( $e );
		}
	}

	/**
	* @name   getArtIdByLike   通过like获取文章的id
	* @param  string   kwds 
	* @return array    artId
	*/
	public function getArtIdByLike( $kwd = '' ){
		try{
			@$artId = $this->wpPdo->query( "SELECT id FROM wp_article WHERE title LIKE '%$kwd%'" , PDO::FETCH_ASSOC );
			return $artId->fetchAll();

		}catch( PDOException $e ){
			echo "通过关键词获取相似文章id失败，原因是：";
			var_dump( $e );
		}
	}

	/**
	* @name   getAllArtTitle   获取所有文章的标题
	* @return array   allTitle
	*/
	public function getAllArtTitle(){
		try{
			@$allTitle = $this->wpPdo->query( "SELECT title FROM wp_article WHERE id>10 LIMIT 100" , PDO::FETCH_ASSOC );
			return $allTitle->fetchAll();
		}catch( PDOException $e ){
			echo "获取文章标题有误，原因是：";
			var_dump( $e );
		}
	}


	/**
	* @name   reduceArrDimens   将二维以上数组降一个维度
	* @param  array  arr
	* @return array  lowDimArr
	* @todo   目前形式有限，只能讲数字为键，子数组仅含有一条信息的数组降维
	*/
	public function reduceArrDimens( $arr = array() ){
		$lowDimArr = array();

		if( empty( $arr ) ){
			return false;
		}

		foreach ($arr as $value) {
			$lowDimArr[] = $value[0];
		}

		return $lowDimArr;
	}

}